#include "component.h"
#include "memberlist.h"
#include "function.h"
#include "membervar.h"
#include "property.h"
#include "memberevent.h"
#include "membertemplate.h"
#include "errorlog.h"
#include "parameterlist.h"
#include "template.h"

Component::Component(const QString& name, MemberList* members, const YYLTYPE& loc )
    : Namespace( loc ), m_name(name), m_members(members)
{
    appendChild(members);
}

Node* Component::getEntry( const QString& name )
{
    Node* p = m_members->firstChild();
    while(p)
    {
        if ( dynamic_cast<MemberFunction*>(p) && dynamic_cast<MemberFunction*>(p)->name() == name )
            return p;
        if ( dynamic_cast<MemberVar*>(p) && dynamic_cast<MemberVar*>(p)->name() == name )
            return p;
        if ( dynamic_cast<Property*>(p) && dynamic_cast<Property*>(p)->name() == name )
            return p;
        if ( dynamic_cast<MemberEvent*>(p) && dynamic_cast<MemberEvent*>(p)->name() == name )
            return p;
        if ( dynamic_cast<MemberTemplate*>(p) && dynamic_cast<MemberTemplate*>(p)->name() == name )
            return p;
        if ( dynamic_cast<Template*>(p) && dynamic_cast<Template*>(p)->name() == name )
            return p;

        p = p->nextSibling();
    }
    return 0;
}

QList<Property*> Component::properties() const
{
    QList<Property*> result;
    Node* p = m_members->firstChild();
    while( p )
    {
        Property* f = dynamic_cast<Property*>(p);
        if ( f )
            result.append(f);
        p = p->nextSibling();
    }
    return result;
}

Property* Component::property(const QString& name) const
{
    Node* p = m_members->firstChild();
    while( p )
    {
        Property* f = dynamic_cast<Property*>(p);
        if ( f && f->name() == name )
            return f;
        p = p->nextSibling();
    }
    return 0;
}

QList<MemberFunction*> Component::memberFunctions() const
{
    QList<MemberFunction*> result;
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberFunction* f = dynamic_cast<MemberFunction*>(p);
        if ( f && f->name() != m_name && f->name() != "~" + m_name )
            result.append(f);
        p = p->nextSibling();
    }
    return result;
}

MemberFunction* Component::constructor() const
{
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberFunction* f = dynamic_cast<MemberFunction*>(p);
        if ( f && f->name() == m_name )
            return f;
        p = p->nextSibling();
    }
    return 0;
}

MemberFunction* Component::destructor() const
{
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberFunction* f = dynamic_cast<MemberFunction*>(p);
        if ( f && f->name() == "~" + m_name )
            return f;
        p = p->nextSibling();
    }
    return 0;
}

QList<MemberEvent*> Component::events() const
{
    QList<MemberEvent*> result;
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberEvent* f = dynamic_cast<MemberEvent*>(p);
        if ( f )
            result.append(f);
        p = p->nextSibling();
    }
    return result;
}

MemberEvent* Component::event(const QString& name) const
{
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberEvent* f = dynamic_cast<MemberEvent*>(p);
        if ( f && f->name() == name )
            return f;
        p = p->nextSibling();
    }
    return 0;
}

QList<MemberTemplate*> Component::memberTemplates() const
{
    QList<MemberTemplate*> result;
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberTemplate* f = dynamic_cast<MemberTemplate*>(p);
        if ( f )
            result.append(f);
        p = p->nextSibling();
    }
    return result;
}

MemberTemplate* Component::memberTemplate(const QString& name) const
{
    Node* p = m_members->firstChild();
    while( p )
    {
        MemberTemplate* f = dynamic_cast<MemberTemplate*>(p);
        if ( f && f->name() == name )
            return f;
        p = p->nextSibling();
    }
    return 0;
}

QList<Template*> Component::templates() const
{
    QList<Template*> result;
    Node* p = m_members->firstChild();
    while( p )
    {
        Template* f = dynamic_cast<Template*>(p);
        if ( f )
            result.append(f);
        p = p->nextSibling();
    }
    return result;
}

void Component::resolveAll()
{
    this->Namespace::resolveAll();

    MemberFunction* c = constructor();
    if ( !c )
        ErrorLog::error( location(), "The component " + m_name + " is lacking a constructor" );
    if ( c->parameterList()->count() != 0 )
        ErrorLog::error( c->location(), "The constructor must not have any parameters" );
}
